package com.yunkeji.api.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TemporalUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yunkeji.api.auth.service.AuthService;
import com.yunkeji.api.auth.vo.AppVipVo;
import com.yunkeji.api.auth.vo.ToLoginVo;
import com.yunkeji.api.gift.vo.GiftInfoVo;
import com.yunkeji.api.user.bo.FriendsListBo;
import com.yunkeji.api.user.bo.UpdateUserInfoBo;
import com.yunkeji.api.user.mapper.ApiAppUserMapper;
import com.yunkeji.api.user.mapper.ApiGiftReceiveMapper;
import com.yunkeji.api.user.mapper.ApiSysHelloDetailMapper;
import com.yunkeji.api.user.service.AppUserAnalyseService;
import com.yunkeji.api.user.service.AppUserInfoService;
import com.yunkeji.api.user.vo.FriendsCount;
import com.yunkeji.api.user.vo.FriendsList;
import com.yunkeji.api.user.vo.UserInfoVo;
import com.yunkeji.common.constant.CacheConstants;
import com.yunkeji.common.core.domain.PageQuery;
import com.yunkeji.common.core.domain.model.LoginUser;
import com.yunkeji.common.core.page.TableDataInfo;
import com.yunkeji.common.enums.app.*;
import com.yunkeji.common.exception.AppServiceException;
import com.yunkeji.common.helper.LoginHelper;
import com.yunkeji.common.msg.PushMessage;
import com.yunkeji.common.msg.bo.PrivateMsg;
import com.yunkeji.common.msg.consts.MsgConstant;
import com.yunkeji.common.utils.StringUtils;
import com.yunkeji.common.utils.redis.RedisUtils;
import com.yunkeji.dao.domain.*;
import com.yunkeji.dao.mapper.*;
import com.yunkeji.dao.vo.AppUserExtVo;
import com.yunkeji.dao.vo.AppUserWalletVo;
import com.yunkeji.dao.vo.UserVisitVo;

import lombok.RequiredArgsConstructor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.mongodb.core.aggregation.DateOperators;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.temporal.TemporalUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Service
public class AppUserInfoServiceImpl implements AppUserInfoService {

    private final ApiAppUserMapper appUserMapper;
    private final AppUserWalletMapper appUserWalletMapper;
    private final AppUserExtMapper appUserExtMapper;
    private final UserFocusMapper userFocusMapper;
    private final SysCityMapper sysCityMapper;
    private final ApiGiftReceiveMapper apiGiftReceiveMapper;
    @Autowired @Lazy AuthService authService;
    private final UserVisitMapper userVisitMapper;
    private final UserCheckMapper userCheckMapper;
    private final UserLevelMapper userLevelMapper;
    @Autowired @Lazy AppUserAnalyseService appUserAnalyseService;
    private final ApiAppUserMapper apiAppUserMapper;
    private final ApiSysHelloDetailMapper apiSysHelloDetailMapper;
    private final PayWithDrawSignMapper payWithDrawSignMapper;
    private final AppUserAlbumMapper appUserAlbumMapper;

    /**
     * 关注
     *
     * @author 老张
     */
    @Override
    public void focus(Long uid) {
        AppUser appUser = appUserMapper.selectById(uid);
        if (appUser == null) {
            throw AppServiceException.accountException("操作失败");
        }
        AppUser ownerUser = appUserMapper.selectById(LoginHelper.getUserId());

        if (ownerUser.getSex().equals(appUser.getSex())) {
            throw AppServiceException.accountException("暂不可关注对方");
        }

        Long userId = LoginHelper.getUserId();
        UserFocus userFocus =
                userFocusMapper.selectOne(
                        Wrappers.lambdaQuery(UserFocus.class)
                                .eq(UserFocus::getFocusUserId, uid)
                                .eq(UserFocus::getFansUserId, userId));
        if (userFocus == null) {
            // 关注
            userFocus = UserFocus.builder().build();
            userFocus.setFansUserId(userId);
            userFocus.setFocusUserId(uid);
            // 查询两人的亲密度
            UserFocus loveValue =
                userFocusMapper.selectOne(
                    Wrappers.lambdaQuery(UserFocus.class)
                        .eq(UserFocus::getSortId, userFocus.getSortIdStr()));
            if(!Objects.isNull(loveValue)){
                // 如果两人有过亲密度则继承之前的亲密度，避免在查看自身亲密关系时出现重复用户但亲密度不同的情况。
                userFocus.setLoveValue(loveValue.getLoveValue());
            }
            userFocus.setFansPlatformId(LoginHelper.getPlatformId());
            userFocus.setFocusPlatformId(appUser.getPlatformId());
            // id组合并排序,构成新的唯一值,亲密度两人公用一个
            userFocus.setSortId(userFocus.getSortIdStr());
            userFocusMapper.insert(userFocus);
        } else {
            // 取反
            userFocus.setDelFlag(userFocus.getDelFlag() == 1 ? 0 : 1);
            userFocusMapper.update(
                    Wrappers.lambdaUpdate(UserFocus.class)
                            .set(UserFocus::getDelFlag, userFocus.getDelFlag())
                            .eq(UserFocus::getFocusUserId, uid)
                            .eq(UserFocus::getFansUserId, userId));
        }
    }

    /**
     * 亲密度排序
     *
     * @author 老张
     */
    @Override
    public TableDataInfo<FriendsList> sortedLoveValue(PageQuery pageQuery) {
        Page<FriendsList> friendsListPage =
                appUserMapper.sortedLoveValue(pageQuery.build(), LoginHelper.getUserId());

        List<FriendsList> records = friendsListPage.getRecords();
        isFocus(records);
        return TableDataInfo.build(friendsListPage);
    }

    /**
     * 我是否关注
     *
     * @author 老张
     */
    private void isFocus(List<FriendsList> records) {
        if (CollectionUtil.isNotEmpty(records)) {
            String ids =
                    records.stream()
                            .map(FriendsList::getId)
                            .map(String::valueOf)
                            .collect(Collectors.joining(","));

            // 传入的id我是否已经关注
            List<UserFocus> focusList = appUserMapper.isFocus(ids, LoginHelper.getUserId());
            if (CollectionUtil.isNotEmpty(focusList)) {
                // key = 我关注的人 value=是否删除 1是0否 0=已经关注
                Map<Long, Integer> collect =
                        focusList.stream()
                                .collect(
                                        Collectors.toMap(
                                                UserFocus::getFocusUserId, UserFocus::getDelFlag));
                records.forEach(
                        item -> {
                            Integer delFlag = collect.get(item.getId());
                            item.setFocusFlag(
                                    delFlag == null
                                            // 为空未关注
                                            ? EnableEnum.NO.getCode()
                                            : EnableEnum.YES.getCode().equals(delFlag)
                                                    // 不为空且已删除=未关注
                                                    ? EnableEnum.NO.getCode()
                                                    // 不为空且未删除删除=关注
                                                    : EnableEnum.YES.getCode());
                        });
            }
        }
    }

    @Override
    public ToLoginVo getUserInfoById(Long id) {

        ToLoginVo toLoginVo = new ToLoginVo();
        // 用户主信息
        AppUser appUser = appUserMapper.selectById(id);
        // 判断账号状态
        if (appUser == null) {
            throw AppServiceException.accountException("该账号不存在");
        }
        if (AppUserStatus.getByCode(appUser.getStatus()) == AppUserStatus.封号) {
            throw AppServiceException.accountException("该账号已被封禁");
        }
        if (AppUserStatus.getByCode(appUser.getStatus()) != AppUserStatus.正常) {
            throw AppServiceException.accountException("账号异常");
        }
        Long uid = appUser.getId();
        // 新增在线状态的返回内容，如果开启了勿扰模式，并且是在线状态，那么在线状态则更改为勿扰。
        appUser.setOnlineStatus(appUser.getDisturbFlag() == 1 && appUser.getOnlineStatus().equals(AppUserOnlineStatus.空闲.getCode()) ? 3 : appUser.getOnlineStatus());
        toLoginVo.setUserInfoVo(BeanUtil.toBean(appUser, UserInfoVo.class));
        // TODO 插别人隐藏钱包
        AppUserWallet appUserWallet = appUserWalletMapper.selectById(uid);
        toLoginVo.setUserWalletVo(BeanUtil.toBean(appUserWallet, AppUserWalletVo.class));
        // 查询扩展信息
        AppUserExt appUserExt = appUserExtMapper.selectById(appUser.getId());

        // 居住地
        Long liveCity = appUserExt.getLiveCity();
        SysCity sysCity = sysCityMapper.selectById(liveCity);

        // 查看是否有在审核的资源
        checkRes(appUserExt);

        AppUserExtVo appUserExtVo = BeanUtil.toBean(appUserExt, AppUserExtVo.class);
        appUserExtVo.setLiveCityName(sysCity.getName());
        toLoginVo.setAppUserExtVo(appUserExtVo);
        // 关注
        UserFocus userFocus =
                userFocusMapper.selectOne(
                        Wrappers.lambdaQuery(UserFocus.class)
                                .eq(UserFocus::getDelFlag, EnableEnum.NO.getCode())
                                .eq(UserFocus::getFansUserId, LoginHelper.getUserId())
                                .eq(UserFocus::getFocusUserId, uid));
        toLoginVo.setFocus(userFocus != null);
        toLoginVo.setLoveValue(userFocus != null ? userFocus.getLoveValue() : BigDecimal.ZERO);
        // 礼物
        List<GiftInfoVo> giftInfoVos = apiGiftReceiveMapper.countGift(uid);
        toLoginVo.setGiftInfoVos(giftInfoVos);

        FriendsCount friendsCount = appUserAnalyseService.friendsCount();
        // 我关注的
        toLoginVo.setFansNum(friendsCount.getFansNum());
        // 关注我的
        toLoginVo.setFocusNum(friendsCount.getFocusNum());
        // vip信息
        AppUserVip appUserVip = AppUserVip.builder().build().selectById(uid);
        toLoginVo.setAppVipVo(BeanUtil.toBean(appUserVip, AppVipVo.class));
        // 检查是否电签
        checkWithdrawSign(toLoginVo, uid);


        // 给对方发送消息 （只有男用户查看女用户时才能进行发送，暂时没有时间限制）
        if (!LoginHelper.getUserId().equals(uid)) {
            AppUser sendUser = appUserMapper.selectById(LoginHelper.getUserId());
            if (SexEnum.男.getCode().equals(sendUser.getSex())){
                AppUserExt ext = appUserExtMapper.selectById(LoginHelper.getUserId());
                if(!Objects.isNull(ext)){
                    long senderPlatformId = LoginHelper.getPlatformId();
//                    String key = CacheConstants.CHECK_INFO_MSG_LIMIT + senderPlatformId + ":" + appUser.getPlatformId();
//                    boolean flag = RedisUtils.setAtomicValueAdd(key, 1, MsgConstant.时间_24H);
//                    if (flag) {
                        PushMessage.sendTextSinglePrivate(
                            senderPlatformId,
                            appUser.getPlatformId(),
                            PrivateMsg.builder()
                                .content("我正在查看你的资料，对你很感兴趣～～")
                                .nickname(ext.getNickName())
                                .headUrl(ext.getHeadUrl())
                                .id(ext.getId())
                                .platformId(senderPlatformId)
                                .build());
//                    }
                }
            }
        }


        // 最近查看
        recentlyVisit(uid);

        return toLoginVo;
     //   return helloFlag(appUser, toLoginVo);
    }

    @Override
    public ToLoginVo getUserInfoByPlatformId(Long platformId) {
        AppUser appUser =
                apiAppUserMapper.selectOne(
                        Wrappers.lambdaQuery(AppUser.class).eq(AppUser::getPlatformId, platformId));

        return getUserInfoById(appUser.getId());
    }

    /**
     * 检查电签
     *
     * @author 老张
     */
    private void checkWithdrawSign(ToLoginVo toLoginVo, Long uid) {
        if (LoginHelper.getUserId().equals(uid)) {
            PayWithDrawSign payWithDrawSign = payWithDrawSignMapper.selectById(uid);
            toLoginVo.setWithdrawSignFlag(
                    payWithDrawSign == null
                                    || !payWithDrawSign
                                            .getStatus()
                                            .equals(CheckStatus.审核通过.getCode())
                            ? EnableEnum.NO.getCode()
                            : EnableEnum.YES.getCode());
        }
    }

    /**
     * 最近查看
     *
     * @author 老张
     */
    private void recentlyVisit(Long uid) {
        // 避免重复提交
        String cache = RedisUtils.getCacheObject("temp:visit:limit:" + uid + "_" + LoginHelper.getUserId());
        if (StringUtils.isNotEmpty(cache)) {
            return;
        }
        RedisUtils.setCacheObject("temp:visit:limit:" + uid + "_" + LoginHelper.getUserId(), "1", Duration.ofSeconds(3));
        if (LoginHelper.getUserId().equals(uid)) {
            return;
        }
        // 存储最近查看
        UserVisit userVisitRecord =
                userVisitMapper.selectOne(
                        Wrappers.lambdaQuery(UserVisit.class)
                                .eq(UserVisit::getToUserId, uid)
                                .eq(UserVisit::getFromUserId, LoginHelper.getUserId()));
        if (userVisitRecord == null) {
            UserVisit userVisit = new UserVisit();
            userVisit.setFromUserId(LoginHelper.getUserId());
            userVisit.setToUserId(uid);
            AppUser fromUser = appUserMapper.selectById(LoginHelper.getUserId());
            AppUserExt fromUserExt = appUserExtMapper.selectById(LoginHelper.getUserId());
            userVisit.setNickName(fromUserExt.getNickName());
            userVisit.setHeadUrl(fromUserExt.getHeadUrl());
            userVisit.setSex(fromUser.getSex());
            userVisitMapper.insert(userVisit);
        } else {
            userVisitRecord.setCount(userVisitRecord.getCount() + 1);
            userVisitMapper.updateById(userVisitRecord);
        }
    }

    /**
     * 是否对他打招呼
     *
     * @author 老张
     */
    private ToLoginVo helloFlag(AppUser appUser, ToLoginVo toLoginVo) {
        if (LoginHelper.getUserId().equals(appUser.getId())) {
            return toLoginVo;
        }

        // @NOTE 这里的需求很奇怪
        // 是否给对方打招呼打招呼
        SysHelloDetail helloDetail =
                apiSysHelloDetailMapper.getHelloDetail(
                        appUser.getPlatformId(), LoginHelper.getPlatformId());
        // 返回null说明未打招呼
        // 返回true,打招呼已回复
        // 返回false,一打招呼未回复
        if (helloDetail == null) {
            // 需要打招呼
            toLoginVo.setHelloFlag(null);
            return toLoginVo;
        } else {
            Long sendUid = helloDetail.getSendUid();
            if (LoginHelper.getPlatformId().equals(sendUid)) {
                // 发送者是自己
                if (helloDetail.getReply().equals(EnableEnum.NO.getCode())) {
                    // 对方未回复
                    // 需要等待回复
                    toLoginVo.setHelloFlag(false);
                    return toLoginVo;
                } else {
                    toLoginVo.setHelloFlag(true);
                    return toLoginVo;
                }
            } else {
                // 发送者是对方,自己可以不用打招呼了
                toLoginVo.setHelloFlag(true);
                return toLoginVo;
            }
        }
    }

    /**
     * 检查是否有在审核的资源
     *
     * @param appUserExt
     */
    private void checkRes(AppUserExt appUserExt) {
        // 检查是否还有在审核的头像
        List<UserCheck> userCheck =
                userCheckMapper.selectList(
                        Wrappers.lambdaQuery(UserCheck.class)
                                // .select(UserCheck::getCheckType)
                                .eq(UserCheck::getStatus, CheckStatus.待审核.getCode())
                                .in(
                                        UserCheck::getCheckType,
                                        CheckType.头像认证.getCode(),
                                        //      CheckType.封面相册认证.getCode(),
                                        CheckType.视频介绍认证.getCode(),
                                        CheckType.语音介绍认证.getCode())
                                .eq(UserCheck::getUserId, appUserExt.getId()));
        if (CollectionUtil.isNotEmpty(userCheck)) {
            //            空对象=未设置
            //            空内容=待审核
            //            改一下规则,因为相册是个数组,现在不是空对象的话,后台不会给你返字段嘛,
            Map<Integer, UserCheck> collect =
                    userCheck.stream()
                            .collect(Collectors.toMap(UserCheck::getCheckType, item -> item));
            UserCheck head = collect.get(CheckType.头像认证.getCode());
            UserCheck voice = collect.get(CheckType.语音介绍认证.getCode());
            UserCheck video = collect.get(CheckType.视频介绍认证.getCode());
            //   UserCheck album = collect.get(CheckType.封面相册认证.getCode());
            if (LoginHelper.getUserId().equals(appUserExt.getId())) {
                // 自己查询自己 空内容=待审核 查自己要显示在审核中
                appUserExt.setHeadUrl(
                        ObjectUtil.isEmpty(head) ? appUserExt.getHeadUrl() : StrUtil.EMPTY);
                appUserExt.setVoiceIntro(
                        ObjectUtil.isEmpty(voice) ? appUserExt.getVideoIntro() : StrUtil.EMPTY);
                appUserExt.setVideoIntro(
                        ObjectUtil.isEmpty(video) ? appUserExt.getVideoIntro() : StrUtil.EMPTY);
                appUserExt.setVideoIntroCoverGif(
                        ObjectUtil.isEmpty(video) ? appUserExt.getVideoIntro() : StrUtil.EMPTY);
            }
        }

        List<AppUserAlbum> appUserAlbums =
                AppUserAlbum.builder()
                        .build()
                        .selectList(
                                Wrappers.lambdaQuery(AppUserAlbum.class)
                                        // 不是自己只能显示审核通过的相册
                                        .eq(
                                                !LoginHelper.getUserId().equals(appUserExt.getId()),
                                                AppUserAlbum::getStatus,
                                                CheckStatus.审核通过.getCode())
                                        .in(
                                                LoginHelper.getUserId().equals(appUserExt.getId()),
                                                AppUserAlbum::getStatus,
                                                CheckStatus.审核通过.getCode(),
                                                CheckStatus.待审核.getCode())
                                        .eq(AppUserAlbum::getUid, appUserExt.getId()));

        appUserExt.setAlbumPics(appUserAlbums);
        // 更新头像 一天一次 审核
        // 更新语音介绍 审核
        // 更新视频介绍 审核
        // 更新相册 一天一次 审核
    }

    /**
     * 单独更新的都是需要审核或是有其他的上传限制 需要审核的资源/动态/封面视频/贴贴墙/真人认证/提现/语音介绍/头像/昵称/相册
     * 封面视频流程：编辑个人资料中选择上传-上传后台-人工审核通过后，展示在首页/未通过审核的不展示在客户端（动态/贴贴墙/语音介绍/头像/昵称/相册）
     * 封面视频的审核状态通知，将以系统消息推送给用户（动态/贴贴墙/语音介绍/头像/昵称/相册））
     */
    @Override
    public void updateUserInfo(UpdateUserInfoBo bo) {
        AppUser user = appUserMapper.selectById(LoginHelper.getUserId());
        AppUserExt userExt = appUserExtMapper.selectById(LoginHelper.getUserId());
        // 更新昵称 取消一天一次 不审核

        // updateNickName(bo);
        // 更新头像 一天一次 审核
        updateHeadUrl(bo, user, userExt);
        // 更新语音介绍 审核
        updateVoice(bo, user, userExt);
        // 更新视频介绍 审核
        updateVideo(bo, user, userExt);
        // 更新相册 一天一次 审核
        updateAlbum(bo, user, userExt);
        // 更新价格
        updatePrice(bo, user);
        if (bo.getAppUser() != null) {
            AppUser appUser = BeanUtil.toBean(bo.getAppUser(), AppUser.class);
            appUser.setId(LoginHelper.getUserId());
            appUserMapper.updateById(appUser);
        }
        if (bo.getAppUserExt() != null) {
            AppUserExt appUserExt = BeanUtil.toBean(bo.getAppUserExt(), AppUserExt.class);
            appUserExt.setId(LoginHelper.getUserId());
            appUserExtMapper.updateById(appUserExt);
        }
    }

    /** 更新相册 */
    private void updateAlbum(UpdateUserInfoBo bo, AppUser user, AppUserExt userExt) {
        if (bo.getAppUserExt() == null
                || CollectionUtil.isEmpty(bo.getAppUserExt().getAlbumPics())) {
            return;
        }
        // 每天用户每日更改头像和名字只能改一次
        Object cacheObject =
                RedisUtils.getCacheObject(
                        CacheConstants.UPDATE_ALBUM_LIMIE + LoginHelper.getUserId());
        if (cacheObject != null) {
            throw AppServiceException.paramException("每天只允许修改一次相册");
        }

        List<UpdateUserInfoBo.Album> albumPics = bo.getAppUserExt().getAlbumPics();

        if (CollectionUtil.isEmpty(albumPics)) {
            // 移除未保存的相册
            AppUserAlbum.builder()
                    .build()
                    .delete(
                            Wrappers.lambdaQuery(AppUserAlbum.class)
                                    .eq(AppUserAlbum::getUid, LoginHelper.getUserId()));
            return;
        }

        // 新创建的审核相册
        List<AppUserAlbum> checkAlbum = new ArrayList<>();
        // 旧的相册
        List<Long> checkOld = new ArrayList<>();

        albumPics.forEach(
                item -> {
                    Long id = item.getId();
                    if (id == null) {
                        // 新增
                        AppUserAlbum build =
                                AppUserAlbum.builder()
                                        .resUrl(item.getResUrl())
                                        .uid(LoginHelper.getUserId())
                                        .build();
                        checkAlbum.add(build);
                    } else {
                        // 不变
                        AppUserAlbum build = AppUserAlbum.builder().build();
                        AppUserAlbum appUserAlbum =
                                build.selectOne(
                                        Wrappers.lambdaQuery(AppUserAlbum.class)
                                                .eq(AppUserAlbum::getId, item.getId())
                                                .eq(AppUserAlbum::getResUrl, item.getResUrl()));
                        if (appUserAlbum == null) {
                            throw AppServiceException.paramException("参数提交异常");
                        }
                        checkOld.add(item.getId());
                    }
                });
        if (checkOld.size() > 0) {
            // 移除未保存的相册
            AppUserAlbum.builder()
                    .build()
                    .delete(
                            Wrappers.lambdaQuery(AppUserAlbum.class)
                                    .eq(AppUserAlbum::getUid, LoginHelper.getUserId())
                                    .notIn(AppUserAlbum::getId, checkOld));
        }
        // 保存新的
        checkAlbum.forEach(
                item -> {
                    appUserAlbumMapper.insert(item);
                    UserCheck build =
                            UserCheck.builder()
                                    .videoAuthUrl(userExt.getVideoAuthUrl())
                                    .userId(LoginHelper.getUserId())
                                    .platformId(user.getPlatformId())
                                    .sex(user.getSex())
                                    .checkRes(
                                            new CheckType.CoverAlbumAuth()
                                                    .setCoverUrl(item.getResUrl())
                                                    .setAlbumId(item.getId())
                                                    .toString())
                                    .checkType(CheckType.封面相册认证.getCode())
                                    .build();
                    userCheckMapper.insert(build);
                });
    }

    /** 更新视频 */
    private void updateVideo(UpdateUserInfoBo bo, AppUser user, AppUserExt userExt) {
        if (bo.getAppUserExt() == null || StrUtil.isEmpty(bo.getAppUserExt().getVideoIntro())) {
            return;
        }
        if (StrUtil.isEmpty(bo.getAppUserExt().getVideoIntroCoverGif())) {
            throw AppServiceException.paramException("动态封面未上传");
        }
        // 检查是否还有在审核的视频
        UserCheck userCheck =
                userCheckMapper.selectOne(
                        Wrappers.lambdaQuery(UserCheck.class)
                                .eq(UserCheck::getStatus, CheckStatus.待审核.getCode())
                                .eq(UserCheck::getCheckType, CheckType.视频介绍认证.getCode())
                                .eq(UserCheck::getUserId, LoginHelper.getUserId()));
        if (userCheck != null) {
            throw AppServiceException.paramException("还有待审核的视频");
        }
        // 创建审核
        userCheckMapper.insert(
                UserCheck.builder()
                        .videoAuthUrl(userExt.getVideoAuthUrl())
                        .userId(LoginHelper.getUserId())
                        .platformId(user.getPlatformId())
                        .sex(user.getSex())
                        .checkRes(
                                new CheckType.CoverVideoAuth()
                                        .setVideoIntroCover(bo.getAppUserExt().getVideoIntroCover())
                                        .setVideoIntroCoverGif(
                                                bo.getAppUserExt().getVideoIntroCoverGif())
                                        .setVideoIntro(bo.getAppUserExt().getVideoIntro())
                                        .toString())
                        .checkType(CheckType.视频介绍认证.getCode())
                        .build());
        // 将bo的昵称置空,因为审核通过之后才能显示
        bo.getAppUserExt().setVideoIntro(null);
        bo.getAppUserExt().setVideoIntroCover(null);
        bo.getAppUserExt().setVideoIntroCoverGif(null);
    }

    /** 更新语音呢 */
    private void updateVoice(UpdateUserInfoBo bo, AppUser user, AppUserExt userExt) {
        if (bo.getAppUserExt() == null || StrUtil.isEmpty(bo.getAppUserExt().getVoiceIntro())) {
            return;
        }
        // 检查是否还有在审核的头像
        UserCheck userCheck =
                userCheckMapper.selectOne(
                        Wrappers.lambdaQuery(UserCheck.class)
                                .eq(UserCheck::getStatus, CheckStatus.待审核.getCode())
                                .eq(UserCheck::getCheckType, CheckType.语音介绍认证.getCode())
                                .eq(UserCheck::getUserId, LoginHelper.getUserId()));
        if (userCheck != null) {
            throw AppServiceException.paramException("还有待审核的语音");
        }
        // 创建审核
        userCheckMapper.insert(
                UserCheck.builder()
                        .videoAuthUrl(userExt.getVideoAuthUrl())
                        .userId(LoginHelper.getUserId())
                        .platformId(user.getPlatformId())
                        .sex(user.getSex())
                        .checkRes(
                                new CheckType.VoiceAuth()
                                        .setVoiceUrl(bo.getAppUserExt().getVoiceIntro())
                                        .toString())
                        .checkType(CheckType.语音介绍认证.getCode())
                        .build());
        // 将bo的昵称置空,因为审核通过之后才能显示
        bo.getAppUserExt().setVoiceIntro(null);
    }

    /** 更新价格 */
    private void updatePrice(UpdateUserInfoBo bo, AppUser user) {
        if (bo.getAppUser() == null || bo.getAppUser().getVideoPrice() == null) {
            return;
        }
        AppUser appUser = appUserMapper.selectById(LoginHelper.getUserId());
        Integer level = appUser.getLevel();
        UserLevel userLevel =
                userLevelMapper.selectOne(
                        Wrappers.lambdaQuery(UserLevel.class).eq(UserLevel::getLevel, level));
        if (!appUser.getVideoAuth().equals(CheckStatus.审核通过.getCode())
                && bo.getAppUser().getVideoPrice() != null) {
            throw AppServiceException.paramException("未真人认证的用户无法设置价格");
        }
        if (userLevel == null && level != 0) {
            throw AppServiceException.paramException("等级异常");
        }
        if (NumberUtil.isGreater(bo.getAppUser().getVideoPrice(), userLevel.getMaxPrice())) {
            throw AppServiceException.paramException(
                    "当前等级可设置的价格范围:" + userLevel.getMinPrice() + "-" + userLevel.getMaxPrice());
        }
        if (NumberUtil.isLess(bo.getAppUser().getVideoPrice(), userLevel.getMinPrice())) {
            throw AppServiceException.paramException(
                    "当前等级可设置的价格范围:" + userLevel.getMinPrice() + "-" + userLevel.getMaxPrice());
        }
    }

    /** 更新头像 */
    private void updateHeadUrl(UpdateUserInfoBo bo, AppUser user, AppUserExt userExt) {
        if (bo.getAppUserExt() == null || StrUtil.isEmpty(bo.getAppUserExt().getHeadUrl())) {
            return;
        }
        // 每日十次且匹配成功才算
        long between = DateUtil.between(new Date(), DateUtil.endOfDay(new Date()), DateUnit.SECOND);
        Boolean isAllow =
                RedisUtils.setAtomicValueAdd(
                        CacheConstants.UPDATE_HEAD_INFO_LIMIE + LoginHelper.getUserId(),
                        3,
                        Integer.parseInt(String.valueOf(between)));
        if (!isAllow) {
            throw AppServiceException.paramException("每天只允许修改三次头像");
        }
        // 检查是否还有在审核的头像
        UserCheck userCheck =
                userCheckMapper.selectOne(
                        Wrappers.lambdaQuery(UserCheck.class)
                                .eq(UserCheck::getStatus, CheckStatus.待审核.getCode())
                                .eq(UserCheck::getCheckType, CheckType.头像认证.getCode())
                                .eq(UserCheck::getUserId, LoginHelper.getUserId()));
        if (userCheck != null) {
            throw AppServiceException.paramException("还有待审核的头像");
        }

        //        Date date = new Date();
        //        long l = DateUtil.between(date, DateUtil.endOfDay(date), DateUnit.SECOND);
        //        RedisUtils.setCacheObject(
        //                CacheConstants.UPDATE_HEAD_INFO_LIMIE + LoginHelper.getUserId(),
        //                LoginHelper.getUserId(),
        //                Duration.ofSeconds(l));
        // 创建审核
        userCheckMapper.insert(
                UserCheck.builder()
                        .videoAuthUrl(userExt.getVideoAuthUrl())
                        .userId(LoginHelper.getUserId())
                        .platformId(user.getPlatformId())
                        .sex(user.getSex())
                        .checkRes(
                                new CheckType.HeadAuth()
                                        .setHeadUrl(bo.getAppUserExt().getHeadUrl())
                                        .toString())
                        .checkType(CheckType.头像认证.getCode())
                        .build());
        // 将bo的昵称置空,因为审核通过之后才能显示
        bo.getAppUserExt().setHeadUrl(null);
    }

    /** 更新昵称 */
    private void updateNickName(UpdateUserInfoBo bo) {
        // 修改昵称
        if (bo.getAppUserExt() == null || StrUtil.isEmpty(bo.getAppUserExt().getNickName())) {
            return;
        }
        // 每天用户每日更改头像和名字只能改一次
        Object cacheObject =
                RedisUtils.getCacheObject(
                        CacheConstants.UPDATE_NICKNAME_INFO_LIMIE + LoginHelper.getUserId());
        // 检查昵称天极流
        if (cacheObject != null) {
            //   throw AppServiceException.paramException("每天只允许修改一次昵称");
        }
        // 检查是否还有在审核的昵称
        UserCheck userCheck =
                userCheckMapper.selectOne(
                        Wrappers.lambdaQuery(UserCheck.class)
                                .eq(UserCheck::getStatus, CheckStatus.待审核.getCode())
                                .eq(UserCheck::getCheckType, CheckType.昵称认证.getCode())
                                .eq(UserCheck::getUserId, LoginHelper.getUserId()));
        if (userCheck != null) {
            throw AppServiceException.paramException("还有待审核的昵称");
        }
        Date date = new Date();
        long l = DateUtil.between(date, DateUtil.endOfDay(date), DateUnit.SECOND);
        RedisUtils.setCacheObject(
                CacheConstants.UPDATE_NICKNAME_INFO_LIMIE + LoginHelper.getUserId(),
                LoginHelper.getUserId(),
                Duration.ofSeconds(l));
        // 创建审核
        userCheckMapper.insert(
                UserCheck.builder()
                        .userId(LoginHelper.getUserId())
                        .checkRes(
                                new CheckType.NickNameAuth()
                                        .setNickName(bo.getAppUserExt().getNickName())
                                        .toString())
                        .checkType(CheckType.昵称认证.getCode())
                        .build());
        // 将bo的昵称置空,因为审核通过之后才能显示
        bo.getAppUserExt().setNickName(null);
    }

    @Override
    public AppUserWalletVo getWalletInfoById(Long userId) {

        AppUserWalletVo userWalletVo = appUserWalletMapper.selectVoById(userId);
        if (userWalletVo == null) {
            throw AppServiceException.accountException("钱包信息异常");
        }
        return userWalletVo;
    }

    /** 访客记录 */
    @Override
    public TableDataInfo<UserVisitVo> visitList(PageQuery query) {
        AppUserVip appUserVip = AppUserVip.builder().build().selectById(LoginHelper.getUserId());

        IPage<UserVisitVo> userVisitVoIPage =
                userVisitMapper.selectVoPage(
                        query.build(),
                        Wrappers.lambdaQuery(UserVisit.class)
                                .ne(UserVisit::getFromUserId, LoginHelper.getUserId())
                                .eq(UserVisit::getToUserId, LoginHelper.getUserId())
                                .orderByDesc(UserVisit::getUpdateTime));
        if (appUserVip.getCommonVipFlag() == EnableEnum.NO.getCode()) {
            // 脱敏
            userVisitVoIPage
                    .getRecords()
                    .forEach(
                            item -> {
                                item.setToUserId(-1L);
                                item.setFromUserId(-1L);
                                item.setNickName("****");
                            });
        }

        return TableDataInfo.build(userVisitVoIPage);
    }

    /** 朋友列表-我关注的-关注我的 */
    @Override
    public TableDataInfo<FriendsList> friendsList(FriendsListBo bo) {
        /** 查询类型 1=我关注的 2=关注我的 */
        if (bo.getType() == 2) {
            // 关注我的
            Page<FriendsList> page =
                    appUserMapper.friendsListFocusMe(bo.build(), LoginHelper.getUserId());
            isFocus(page.getRecords());

            return TableDataInfo.build(page);
        } else {
            // 我关注的
            Page<FriendsList> page =
                    appUserMapper.myFocusfriendsList(bo.build(), LoginHelper.getUserId());
            return TableDataInfo.build(page);
        }
    }

    /**
     * 获取对立的性别 男返回女 女返回男
     *
     * @param loginUser
     * @return
     */
    @Override
    public SexEnum getOppositeSex(LoginUser loginUser) {
        AppUser appUser = appUserMapper.selectById(loginUser.getUserId());
        Integer sex = appUser.getSex();
        SexEnum sexByCode = SexEnum.getSexByCode(sex);
        if (sexByCode.getCode() == SexEnum.未知.getCode()) {
            throw AppServiceException.paramException("性别未知");
        }
        return SexEnum.getOpposite(sexByCode);
    }
}
